;(function($, undefined){
    function SuperTable(opt, ele){
        this.ele = ele;
        this.options = opt;
        this.init();
    }
    SuperTable.prototype = {
        constructor: SuperTable,
        init: function(){	//初始化方法
            var that = this, _opt = that.options, events = _opt.events;
            if(_opt.pageination){
            	_opt.pageConfig.pagerid = that.ele.attr("id");
                that.ele[_opt.pageination](_opt.pageConfig, function(data, req){
                	if(_opt.pageination == "paginationForNum"){	//根据对应的分页插件名称而定
                		_opt.cacheData = [];
                		_opt.selects = {};
                		$(that.ele).find("tbody").empty();
                	}
                    _opt.jsonData = {list: data};
                    _opt.cacheData = _opt.cacheData.concat(data);
                    _opt.requestData = req;
                    _init();
                });
            }else
                _init();
            function _init(){
                that.showData();	//数据显示
                var $b = $(that.ele.parent());
                !$(that.ele).data("isFixed") && $b.attr("supertable_parent", "1");
                _opt.autoHeight && $b.css("height", $b.parent().height() - $b.position().top || "auto");
                if(_opt.fixedTitle){	//表头固定
                    var timer = null;
                    $(window).resize(function(){
                        timer && clearTimeout(timer);
                        timer = setTimeout(function(){fixedTitle(that);}, 30);
                    });
                }else{
                	_opt.autoHeight && $(window).resize(function(){
                        $b.css("height", $b.parent().height() - $b.position().top || "auto");
                    });
                }
                if(!that.ele.data("isInit")){
                    if(_opt.selectenable){	//选择行变色
                        fnAddEevnt(events, "click", {
                            selector: "tr",
                            func: selectTr
                        }, true);
                    }
                    if(_opt.checkbox){	//checkox
                        fnAddEevnt(events, "click", {
                            selector: "input[type='checkbox']",
                            parent: "thead tr  th, thead tr  td",
                            func: function(){fnCheckAll(that.ele, true);}
                        }, true);
                    }
		    if(_opt.sort){		//是否支持排序
                    	fnAddEevnt(events, "click", {
                            selector: "th[data-sort-target], td[data-sort-target]",
                            parent: "thead tr",
                            func: function(e, target){fnSort(that, e, target);}
                        }, true);
                    }
                    if(events && !$.isEmptyObject(events)){
                        for(var eventType in events){
                            var _event = events[eventType];
                            if(typeof _event === "object"){
                                if(!(_event instanceof Array)){	//如果没有多个事件
                                    _event = [_event];
                                }
                                for (var i = 0; i < _event.length; i++) {
                                	var _e =_event[i];
	                                if(_e.triggerBySelectAll)	//标识是否在点击全选时触发（仅点击全选时）
	                                	_opt.selectAllEvents.push(_e);
                                }
                                that.bindEvent($b, eventType, function(_event){
                                    return function(e){
                                        var e = e || window.event, target = $(e.target || e.srcElement);
                                        for (var i = 0; i < _event.length; i++) {
                                            var _e =_event[i];
                                            if(/\btr$/.test(_e.selector)) _e.selector += ":not(.noclick)";
                                            var selectorTarget = target.closest(_e.selector), parent = target.closest(_e.parent || "tbody");
                                            if(parent.length > 0 && selectorTarget.length > 0){
                                                _e.func(e, selectorTarget);
                                            }
                                        };
                                    };
                                }(_event));
                            }
                        }
                    }
                }
                that.ele.data("isInit", true);
            }
        },
        reload: function(){
            $(this.ele).find("tbody").empty();
            this.options.cacheData = [];
            this.init();
        },
        reQuery: function(options, isNew){ //isNew非true时 表示合并上一次的查询条件
        	$(this.ele).find("tbody").empty();
        	options = options || {};
        	this.options.selects= {};
            this.options.cacheData = [];
            var tf = typeof isNew;
            if(tf !== "function" && !isNew)
        		options.requestData = $.extend(this.options.requestData, options.requestData || {});
            if(tf == "function")
            	arguments[1]();
            else if(tf !== "function" && typeof arguments[2] == "function")
            	arguments[2]();
            if(this.options.checkbox) $(this.ele).closest("[supertable_parent=1]").find(".title input[type=checkbox]").attr("checked", false);	//重新查询取消全选
            this.options.pageConfig = $.extend(this.options.pageConfig,  options);
            this.init();
        },
        bindEvent: function(eventTarget, eventType, eventFunc){	//绑定事件, 提供三个参数 事件源对象(可以是选择器) 事件类型 事件方法体
            $(eventTarget).on(eventType, function(e){
                eventFunc(e);
            });
        },
        showData: function(){	//数据显示方法
            var _opt = this.options, _emptyData = _opt.emptyData;
            if(_opt.jsonData && _opt.jsonData.list && _opt.jsonData.list.length > 0){
                _opt.showData(_opt.jsonData, _opt.requestData);
                if(_opt.fixedTitle){	//表头固定
                	var that = this;
                    setTimeout(function(){fixedTitle(that)}, 50);
                }
                //fnCheckAll(this.ele);
            }else
                _emptyData(this);	//空数据方法
        },
        getSelectData: function(){
            var _opt = this.options;
            return _opt.getSelectData();
        }
    };

    function fixedTitle(superTable){
    	var $table = $(superTable.ele), //$table 为需要固定表头的表格jq对象
		$tableParent = $table.parent(),
		oOpt = superTable.options,
		guid = $table.attr("data-id") ? $table.attr("data-id") : fnGetUID();
    	$table.attr("data-id", guid);

		var $thead, $tbody = $table.find("tbody"), $newThead = null;

		var $fixedTableTitle = $fixedTableTbody = null;
		if(!$table.data("isFixed")){

			$thead = $table.find("thead");
			$newThead = $thead.clone(true);

			var $newTableForThead = $("<table class='table table-hover'></table>");	//创建新的表格用于存放新的固定表头
			$newTableForThead.append($newThead);

			$table.data("thead_bak", $thead);	//缓存当前的表头
			$thead.remove();	//删除当前的表头

			$fixedTableTitle = $("<div class='fixedTableTitle' id='thead_"+ guid +"'></div>").append($newTableForThead);
			$fixedTableTbody = $("<div class='fixedTableTbody' id='tbody_"+ guid +"'></div>").append($table, $table.nextAll());

			$tableParent.append($fixedTableTitle, $fixedTableTbody);
			$table.data("isFixed", true);
		}else{
			$fixedTableTitle = $("#thead_" + guid);
			$fixedTableTbody = $("#tbody_" + guid);
			$thead = $newThead = $fixedTableTitle.find("thead");
		}
		var $theadChilds = $newThead.find("tr:eq(0)").children('td, th');	//表头的列数
		var $tbodyChilds = $tbody.find("tr:eq(0)").children("td, th");
		var colLength = $theadChilds.length; //获取表格列数
		var dataCol = $tbodyChilds.length;	//实际的第一行的列数

		if(dataCol == colLength){ //当没有缺少列时
			for(var i=0; i<colLength; i++){
				var w = $($tbodyChilds[i]).outerWidth();
				$($theadChilds[i]).css({"width": w + "px", "max-width": w + "px"}).attr("title", $($theadChilds[i]).text());
			}
		}
		setTimeout(function(){$fixedTableTitle.css("width", $table.outerWidth() + "px")}, 30);
		var $SuperTableParent = $fixedTableTbody.closest("[supertable_parent]");
		if(oOpt.autoHeight){	//动态设置表格容器的高度
			$SuperTableParent.css("height", $SuperTableParent.closest("#mainContent").height() - $SuperTableParent.position().top);
			$fixedTableTbody.css("height", $SuperTableParent.closest("#mainContent").height() - $fixedTableTbody.position().top || "auto");
		}
    }

    function selectTr(e, target){	//选择行方法
        var superTableParent = target.closest('[supertable_parent]'), superTable = target.closest("table").data("superTable");
        var opt = superTable.options, selects = {}, index = target.index();
        var check = opt.checkbox.toString() == "true" || opt.checkbox.toString() == "false" ? 0 : opt.checkbox;
        if(opt.checkbox && ($(e.target).attr("type") == "checkbox" || $(e.target).closest("td").index() == check) ){

            selects = opt.selects;
            if(selects[index]){	//如果以选中
                delete selects[index];
                target.removeClass("select").children(":eq(" + check + ")").find("input[type='checkbox']").attr("checked",false);
                superTableParent.find("thead tr").children(":eq(" + check + ")").find("input[type='checkbox']").attr("checked",false);
            }else{
                target.addClass("select").children(":eq(" + check + ")").find("input[type='checkbox']").attr("checked",true);
                selects[index] = 1;
                if(fnGetNum(selects) == superTableParent.find("tbody tr").length){
                    superTableParent.find("thead tr").children(":eq(" + check + ")").find("input[type='checkbox']").attr("checked",true);
                }
            }
        }else{
            selects = opt.selects = {};
            superTableParent.find(".select").removeClass("select").each(function(index, ele){
                $(ele).children(":eq(" + check + ")").find("input[type='checkbox']").attr("checked",false);
            });
            target.addClass("select").children(":eq(" + check + ")").find("input[type='checkbox']").attr("checked",true);
            var isChecked = superTableParent.find("tbody tr").length == 1 ? true : false;
            superTableParent.find("thead tr").children(":eq(" + check + ")").find("input[type='checkbox']").attr("checked", isChecked);
            selects[index] = 1;
        }
    }

    function fnSort(that, e, target){
    	var sortKey = that.options.sortKey, $target = $(target);
    	var data = {}, dire=["ASC", "DESC"], index = parseInt($target.attr("data-sort-dire")) || 0;
    	data[sortKey.orderByFieldName] = $target.attr("data-sort-target");
    	data[sortKey.orderDirection] = dire[index];
    	that.reQuery({
			requestData: data
		});
    	var klass = ["asc", "desc"];
    	$target.closest("tr").find(".sort-asc, .sort-desc").removeClass("sort-asc sort-desc");
    	$target.attr("data-sort-dire", !index - 0).addClass("sort-asc sort-desc").removeClass("sort-"+klass[index^1]);
    }

    function fnCheckAll(table, isClick){	//全选操作
        var superTable = table.data("superTable");
        var superTableParent = table.closest('[supertable_parent]');
        if(!superTable) return;
        var opt = superTable.options, selects = opt.selects = {};
        var check = opt.checkbox.toString() == "true" || opt.checkbox.toString() == "false" ? 0 : opt.checkbox;
        if(opt.checkbox && superTableParent.find("thead tr").children(":eq(" + check + ")").find("input[type='checkbox']:checked").length > 0){
            $(table).find("tbody tr").each(function(index, ele){
                $(ele).addClass("select").children(":eq(" + check + ")").find("input[type='checkbox']").attr("checked",true);
                selects[index] = 1;
            });
        }else if(isClick && opt.checkbox && superTableParent.find("thead tr").children(":eq(" + check + ")").find("input[type='checkbox']:checked").length == 0){
            $(table).find("tbody tr").each(function(index, ele){
                $(ele).removeClass("select").children(":eq(" + check + ")").find("input[type='checkbox']").attr("checked",false);
                delete selects[index];
            });
        }
        for(var i=0; i<opt.selectAllEvents.length; i++){
        	var _e =opt.selectAllEvents[i];
                _e.func();
        }

    }

    function fnGetNum(map){	//获取私有属性个数
        var num = 0;
        for(var p in map){
            if(map.hasOwnProperty(p)){
                num++;
            }
        }
        return num;
    }

    function  getVisualLength(str, fontSize) {
    	fontSize = fontSize || 12;
    	var $rule = $("<div id='visualLength_dom' style='width: auto; position: absolute;visibility: hidden; white-space: nowrap; font-size: "+fontSize+"px;'>"+str+"<div>").appendTo("body");
    	var w = $rule.width();
    	$("#visualLength_dom").remove();
    	return w;
    }

    function fnAddEevnt(events, type, event, isPriority){	//添加事件，isPriority标识事件是否优先触发
        if(events[type]){
            if(events[type] instanceof Array){
                isPriority ? events[type].splice(0, 0, event) : events[type].push(event);
            }else{
                events[type] = ["event." + type, event];
            }
        }else{
            events[type] = [event];
        }
    }

    function fnGetHiddenParent(elem){	//获取指定节点最上级的隐藏元素
    	var $elem = $(elem), $parents = $elem.parents(), $parent = null;
    	$parents.each(function(){
    		var $this = $(this);
    		if($this.css("display") == "none"){
    			$parent = $this;
    			return false;
    		}
    	});
    	return $parent;
    }

    function fnResetCSS( elem, prop ) {  	//设置新属性并保存旧属性
        var old = {}, $elem = $(elem);
        for ( var i in prop ) {
            old[i] = $elem.css(i);
            $elem.css(i, prop[i]);
        }
        return old;
    }

    function fnGetUID(){
    	return Math.random().toString(32).substr(2);
    }

    var defaults = {	//默认配置属性
        jsonData: {}, 	//数据源
        showData: $.noop, //数据显示方法
        emptyData: emptyData, 	//空数据调用的方法
        autoHeight: true,	//是否启用高度自动
        selectenable: true, //是否启用行选中
        checkbox: false,	//启用checkbox  true, false, 列号
        sort:	true,		//启用排序（需要在对应td/th中添加data-sort-target='XXX' class='sort'  要排序自动名称）
        sortKey:{
        	orderByFieldName: "orderByFieldName",	//对应后台接受的排序字段名
        	orderDirection: "orderDirection"	//对应后台接收的排序方式字段名
        },
        selectAllEvents: [], //在点击全选时触发（仅点击全选时）的事件列表
        selects: {},	//选中行的对象集合
        cacheData: [],	//缓存列表数据
        getSelectData: _getSelectData, //获取选中行数据（json）
        fixedTitle: true, //表头固定
        fixedScrollEle: "",
        //scrollXELE: document.body, //出横向滚动条的对象（有关表头固定）
        pageination: "paginationForNum",	//分页插件jquery调用对象（需引入paginationForNum。js  或者 scrollpagination.js），为空是不分页		//注意修改showData中tbody的清空代码
        pageConfig: {},	//分页配置详见各分页实现js
        events: {
            /*click: [{selector: "td", func: $.noop}, {selector: "tr", parent:"tbody", func: $.noop}]	//此处按顺序优先级执行, 但无同步处理不保证执行完成优先级
             */
        }	//表格事件的绑定
    };
    $.fn.superTable = function(options){	//superTabel jQuery对象调用
        var $this = $(this), data = $this.data("superTable"),
            opt = $.extend(true, {}, defaults, options);
        !data ? ($this.data("superTable", data = new SuperTable(opt, $this))) : data.reQuery(opt.pageConfig || {});
        return data;
    };

    function _getSelectData(){
        var _arr = [], that = this, _selects = that.selects, _cacheData = that.cacheData;
        for(var p in _selects){
            _arr.push(_cacheData[p]);
        }
        return _arr;
    }

    function emptyData(obj){
    	var table = obj.ele,
    		len = table.find("thead tr").children().length;
    	var dataEmpty = LanguageParsing("common.data.empty");
    	var str = "<tr class='noclick'><td colspan='"+len+"'>" + dataEmpty + "</td></tr>";
    	table.find("thead").css({"position": "relative"});
    	table.find("tbody").html(str);
    }

})(jQuery);
